package com.netty.java.nio;

import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Author: TongRui乀
 * @Date: 2020/1/5 11:58
 * @description：  测试Nio的三大组件  Buffer  Channel  Selector
 */
@Slf4j
public class TestNio {

    /**
     *  测试 buffer
     */
    public static void test_01(){

        IntBuffer intBuffer = IntBuffer.allocate(10);

        for (int i = 0; i < 10; i++) {
            intBuffer.put(i);
        }

        // 将指针或者索引重新指向0 用于读取
        intBuffer.flip();

        // 获取缓存中的内容
        for (int i = 0; i < 10; i++) {
            System.out.println(intBuffer.get());
        }

        // 常用API
        // 索引位置
        System.out.println(intBuffer.position());
        // 复制一份
        System.out.println(intBuffer.slice().equals(intBuffer));
        // buffer 容量
        System.out.println(intBuffer.capacity());
        // 当前索引位置 到 limit 位置之间的数
        System.out.println(intBuffer.remaining());


    }

    /**
     *  测试 Buffer 和 FileChannel 同时使用
     *
     *  将内容从文件A 中取出 打印 然后存到 文件B中
     *
     */
    public static void test_02(){

        // 创建文件流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("a.txt");
            fos = new FileOutputStream("b.txt");

            // 创建通道  FileChannel
            FileChannel inputChannel = fis.getChannel();
            FileChannel outputChannel = fos.getChannel();

            // 创建Buffer
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            // 将输入文件流写入buffer

            while(inputChannel.read(buffer) != -1){
                // 反转buffer索引
                buffer.flip();
                outputChannel.write(buffer);
                buffer.clear();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     *  使用Channel 拷贝文件
     */
    public static void test_03(){

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("a.txt");
            fos = new FileOutputStream("c.txt");

            // 创建通道  FileChannel
            FileChannel inputChannel = fis.getChannel();
            FileChannel outputChannel = fos.getChannel();

            // 将当前inputChannel 拷贝到 指定outputChannel
            inputChannel.transferTo(0, inputChannel.size(), outputChannel);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    /**
     *  mappedByteBuffer
     */
    public static void test_04(){

        RandomAccessFile accessFile = null;

        try {
            accessFile = new RandomAccessFile("a.txt", "rw");

            FileChannel fileChannel = accessFile.getChannel();

            /**
             *  参数 size ： 映射区域的大小
             */
            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 2);

            mappedByteBuffer.put(1, (byte)'中');

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(accessFile != null){
                try {
                    accessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }



    public static void main(String[] args) {
        test_04();

    }

}
